package com.hzh.jetpackcomposecompositionlocal.sample

import android.widget.Space
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.hzh.jetpackcomposecompositionlocal.ui.theme.DN_Compose_LearnTheme

/**
 * @author huangzehui
 * @date 2025/8/19 13:34 周二
 * @description
 *
 * 47-两种创建方式(staticCompositionLocalOf、compositionLocalOf)对比
 * https://www.bilibili.com/video/BV1ob4y1a7ad?spm_id_from=333.788.player.switch&vd_source=e07cc8cc94eb22bd76722071b03cd199&p=47
 *
 *
 * 结论：
 * staticCompositionLocalOf ：使用这个方式，有引用 staticCompositionLocalOf.current ，被 CompositionLocalProvider 包裹的所有
 * 可组合函数都会重组（如果展示的信息基本上不会变化，使用这个方式可以节省一些性能）
 *
 * compositionLocalOf : 使用这个方式，只有引用 staticCompositionLocalOf.current 的那个可组合函数才会发生重组
 *
 */

var isStatic = true
var compositionLocalName = ""
val currentLocalColor = if (isStatic) {
    compositionLocalName = "StaticCompositionLocal 场景"
    staticCompositionLocalOf { Color.Black }
} else {
    compositionLocalName = "DynamicCompositionLocal 场景"
    compositionLocalOf { Color.Black }
}

// 重组标记，组件第一次加载时，recomposeFlag为Init重组之前(也就是第二次加载之前)，将recomposeFlag
// 设置为 Recompose
var recomposeFlag = "Init"


@Composable
fun CompositionSample4Enter() {
    DN_Compose_LearnTheme {
        Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
            Column(modifier = Modifier.padding(innerPadding)) {

                CompositionSample4()

            }
        }

    }
}

@Composable
fun CompositionSample4() {
    val (color, setColor) = remember { mutableStateOf(Color.Green) }

    Box(
        modifier = Modifier.fillMaxSize(),
        contentAlignment = Alignment.Center
    ) {
        Column(horizontalAlignment = Alignment.CenterHorizontally) {
            Text(text = compositionLocalName)
            Spacer(modifier = Modifier.height(20.dp))

            // 3个TaggedBox 组件，只有"Middle"使用了CompositionLocal
            CompositionLocalProvider(currentLocalColor provides color) {
                TaggedBox(tag = "Wrapper: $recomposeFlag", size = 400.dp, background = Color.Red) {
                    TaggedBox(
                        tag = "Middle: $recomposeFlag",
                        size = 300.dp,
                        background = currentLocalColor.current
                    ) {
                        TaggedBox(
                            tag = "Inner: $recomposeFlag",
                            size = 200.dp,
                            background = Color.Yellow
                        )
                    }
                }
            }

            Spacer(modifier = Modifier.height(20.dp))

            // 点击按钮改变状态，将颜色设置为蓝色，观察3个TaggedBox组件是否重组
            Button(onClick = {
                setColor(Color.Blue)
                recomposeFlag = "Recompose"
            }) {
                Text(text = "Change Theme")
            }

        }
    }
}

@Composable
fun TaggedBox(tag: String, size: Dp, background: Color, content: @Composable () -> Unit = {}) {
    Column(
        modifier = Modifier
            .size(size)
            .background(background),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text(text = tag)
        Box(
            modifier = Modifier.fillMaxSize(),
            contentAlignment = Alignment.Center
        ) {
            content()
        }
    }
}